/*
 * Process.scala
 */

package acorn.jash

import java.io.{InputStream => IS,
                InputStreamReader => ISR,
                BufferedReader => BR,
                PrintStream => PS}


class Process(cmd:String, expr:Expr=null) {

  def run(block:Boolean=true) {
    Shell.debug("cmd => " + cmd)
    val proc = Runtime.getRuntime.exec(cmd,null,Shell.wd.asFile)

    if (null != expr) {
      if (null != expr.in) {
        startThread{
          val ps = new PS(proc getOutputStream)
          var msg = expr.in get;
          while (msg != null) {
            ps print(msg, 0, msg.length); ps flush;
            msg = expr.in get;
          }
          ps close
        }
      }

      startThread{
        readLines(proc getErrorStream, expr.err);
      }

      // println("read output from process")
      // startThread(expr.out put readLines(proc getInputStream))
      // expr.out put readLines(proc getInputStream)
      readLines(proc getInputStream, expr.out)
    }

    if (block) proc.waitFor else 0
  }


  def readLines(is:IS, output:Output) {
    val br = new BR(new ISR(is))
    def readLines:Unit = br.readLine match {
      case null => output flush; is close
      case s:String => output putln s; readLines
    }
    // try {readLines} catch { case _ => ""}
    readLines
  }


  private def startThread(f : => Unit) {
    new Thread(new Runnable { def run = f}) start
  }
}
